package net;

import enums.TextBundleEnum;
import enums.URLEnum;
import gui.panel_new.evaluation.professor.StudentMarksPanel;
import misc.BundlesProvider;
import misc.ExportDataPreferences;
import model.eval.Test;

import javax.swing.*;
import javax.swing.text.JTextComponent;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;

/*

    This file is part of Logica-Logike.

    Logica-Logike is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation version 3 of the License.

    Logica-Logike is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Logica-Logike.  If not, see <http://www.gnu.org/licenses/>.

 */
/**
 * Clase servidor usada para el envio de evaluaciones;
 *
 * @author Jose Martin Rozanec;
 */
public class Server extends Thread {
    private ServerSocket serverSocket;
    private List<TCPThread> threads;
    private List<UserData> clients;
    private long clientID;
    private int maxConnections;
    private Test test;
    private JTextComponent component;
    private List<UserData> currentTestClientsRegistry;
    private StudentMarksPanel studentsMarksPanel;

    private ExportDataPreferences exportPreferences;

    private ResourceBundle textBundle;

    /**
     * Constructor;
     *
     * @param connections;
     */
    public Server(int connections, Test test, StudentMarksPanel studentsMarksPanel, ExportDataPreferences exportPreferences) {
        textBundle = BundlesProvider.getBundle(URLEnum.TEXT_BUNDLE);
        currentTestClientsRegistry = new ArrayList<UserData>();
        this.studentsMarksPanel = studentsMarksPanel;
        this.exportPreferences=exportPreferences;
        this.test = test;
        clientID = 0;
        threads = new ArrayList<TCPThread>();
        this.maxConnections = connections;
        /* create socket server and wait for connection requests */
        try {
            serverSocket = new ServerSocket(5041);
        }
        catch (IOException e) {
            System.out.println("Exception on new ServerSocket: " + e);
        }
    }

    /**
     * Metodo run;
     */
    public void run() {
        System.out.println("Server waiting for client on port " + serverSocket.getLocalPort());
        while (clientID < maxConnections) {
            setComponentText(textBundle.getString(TextBundleEnum.SERVER_WAITING.toString()));
            Socket socket = null;  // accept connection
            try {
                socket = serverSocket.accept();
                setComponentText(textBundle.getString(TextBundleEnum.CLIENT_ASKED_CONNECTION.toString()));
                setComponentText(textBundle.getString(TextBundleEnum.CONNECTION_ASSIGNED.toString()));
                clientID++;
                setComponentText(textBundle.getString(TextBundleEnum.STARTING_CONNECTION.toString()));
                TCPThread tcpThread = new TCPThread(socket, test, clientID, currentTestClientsRegistry, studentsMarksPanel,exportPreferences);
                tcpThread.setComponent(component);
                tcpThread.start();
                threads.add(tcpThread);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * Permite acceder el socket de servidor;
     *
     * @return ServerSocket;
     */
    public ServerSocket getServerSocket() {
        return serverSocket;
    }

    /**
     * Permite acceder la evaluacion seleccionada;
     *
     * @return Test;
     */
    public Test getTest() {
        return test;
    }

    public static void main(String[] args) {
        Test test = new Test();
        test.setMinutes(65);
//        Utiles.serialize(test,"C:\\Users\\Jose\\Desktop\\as.tst");
        Server server = new Server(3, test, 
                new StudentMarksPanel(12,new ExportDataPreferences(), new JButton(),new JButton(),new JFileChooser()),
                new ExportDataPreferences());
        server.start();
    }

    /**
     * Permite setear un JTextComponent sobre el cual se notificaran los estados de las
     * conexiones con los diferentes clientes;
     *
     * @param component;
     */
    public void setComponent(JTextComponent component) {
        this.component = component;
    }

    /**
     * Metodo que administra el agregado de texto al JTextComponent;
     *
     * @param text - String;
     */
    private void setComponentText(String text) {
        if (component != null) {
            if (!component.getText().equals("")) {
                component.setText(component.getText() + "\n" + text);
            } else {
                component.setText(text);
            }
        }
    }
}
